package scan

import (
	"context"
	"log"
	"math/big"

	"github.com/fbsobreira/gotron-sdk/pkg/client"
	"github.com/fbsobreira/gotron-sdk/pkg/common"
	"github.com/fbsobreira/gotron-sdk/pkg/proto/api"
	"github.com/fbsobreira/gotron-sdk/pkg/proto/core"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/protobuf/proto"
)

var (
	StartBlock int64 = 64266761
	Client     *client.GrpcClient
	// 收款地址
	ReciveAddress string = ""
)

type Transactions []struct {
	TxID    string `json:"txID"`
	RawData struct {
		Contract []struct {
			Parameter struct {
				Value struct {
					Amount       int64  `json:"amount"`
					OwnerAddress string `json:"owner_address"`
					ToAddress    string `json:"to_address"`
				} `json:"value"`
				TypeURL string `json:"type_url"`
			} `json:"parameter"`
			Type string `json:"type"`
		} `json:"contract"`
	} `json:"raw_data"`
	RawDataHex string `json:"raw_data_hex"`
}
type RowData struct {
	Timestamp      int64  `json:"timestamp"`
	TxTrieRoot     string `json:"txTrieRoot"`
	ParentHash     string `json:"parentHash"`
	Number         int    `json:"number"`
	WitnessAddress string `json:"witness_address"`
	Version        int    `json:"version"`
}

func init() {
	Client = client.NewGrpcClient("")
	Client.Start(grpc.WithTransportCredentials(insecure.NewCredentials()))
}

// 获取最近区块
func GetLatestBlcok(ctx context.Context) (int64, error) {
	block, err := Client.GetNowBlock()
	if err != nil {
		return 0, err
	}
	return block.BlockHeader.GetRawData().Number, nil
}

// 获取交易列表
func GetTranscations() (transcations []*api.TransactionExtention, err error) {
	block, err := Client.GetNowBlock()
	if err != nil {
		return []*api.TransactionExtention{}, err
	}
	return block.Transactions, nil
}

// 扫块
func ScanBlock(ctx context.Context) {
	// 64266761
	log.Default().Printf("StartBlock:%v\n", StartBlock)
	if StartBlock == 0 {
		block, err := GetLatestBlcok(ctx)
		if err != nil {
			log.Default().Printf("GetLatestBlcok:%v\n", err)
			return
		}
		StartBlock = block
	} else {
		StartBlock++
	}

	Transcations, err := GetTranscations()
	if err != nil {
		log.Default().Printf("GetTranscations:%v\n", err)
		return
	}
	for _, v := range Transcations {
		t_contract := v.Transaction.RawData.Contract[0]
		switch t_contract.Type {
		case core.Transaction_Contract_TransferContract:
			tc := &core.TransferContract{}
			err := proto.Unmarshal(t_contract.Parameter.GetValue(), tc)
			if err != nil {
				log.Default().Printf("proto.Unmarshal:%v\n", err)
			}
			// 充值地址
			rechargeAddress := common.EncodeCheck(tc.OwnerAddress)
			// fmt.Println("充值地址:", rechargeAddress)
			// 接收到账户充值
			if common.EncodeCheck(tc.ToAddress) == ReciveAddress {
				// TODO

				// 1 存储原始数据
				// 2 增加充值金额
				// 3 给充值地址增加次数或能量
			}
			t_amount := big.NewInt(tc.Amount)
			divisor := big.NewInt(1000000)
			result := new(big.Int)
			log.Default().Printf("amount:%v\n", result.Div(t_amount, divisor))
		}
	}
}
